'use client';

import { type FormEvent, useEffect, useRef, useState } from 'react';
import { useMutation } from '@tanstack/react-query';
import { updatePostTemplate } from '@/services/api';
import diff from 'microdiff';
import type { IDifference, IPostTemplate } from '@/interfaces';
import useToast from '@/hooks/useToast';
import { getDiffData } from '@/lib/tool';
import classNames from 'classnames';
import ContentHtml from '@/app/[locale]/common/content/html';
import dynamic from 'next/dynamic';
import EditorSuspense from '@/app/[locale]/posts/[id]/edit/editor/load';
import {
  handleEditorBeforeunload,
  handleEditorSave,
  handleEditorStatusChanges,
} from '@/lib/editor/handle';
import { getEditorContentHtml, setEditorContentHtml } from '@/lib/editor';
import Box from '@/app/[locale]/admin/common/box';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

const DynamicEditor: any = dynamic(
  () => import('../../../../../posts/[id]/edit/editor/editor'),
  {
    loading: () => <EditorSuspense />,
    ssr: false,
  },
);

export default function UpdatePostTemplateContent({
  source,
  translatedFields,
}: {
  source: IPostTemplate;
  translatedFields: PrefixedTTranslatedFields<'postTemplateAdminPage'>;
}) {
  const { show } = useToast();
  const [form, setForm] = useState<{
    content?: string;
  }>({
    content: source.content ?? '',
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const [isPreview, setIsPreview] = useState(false);
  const [previewContent, setPreviewContent] = useState('');
  const editorRef = useRef<any>();
  const [isActive, setIsActive] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const isDirty = useRef(false);
  const isLoadingSave = useRef(false);
  const [isReady, setIsReady] = useState(false);
  const [isDisabledSave, setIsDisabledSave] = useState(true);

  const updatePostTemplateMutation = useMutation(updatePostTemplate);

  useEffect(() => {
    const diffData = diff(
      {
        content: source.content,
      },
      form,
    );
    setDifferenceData(diffData);
    setIsDisabledSave(diffData.length === 0);
  }, [form, source]);
  useEffect(() => {
    const selector = document.querySelector('.yw-navbar-layout');
    if (selector) {
      selector.classList.remove('sticky-top');
    }

    return () => {
      if (selector) {
        selector.classList.add('sticky-top');
      }
    };
  }, []);

  function getContent(data?: any) {
    return getEditorContentHtml(editorRef.current, data);
  }

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    e.stopPropagation();

    const editor = editorRef.current;
    if (!editor) {
      show({
        type: 'DANGER',
        message: translatedFields.tip.editorDoesNotExist,
      });
      return;
    }

    await handleEditorSave({
      editor,
      isDirty,
      setIsActive,
      setIsSaving,
      callback: onClickSaveCore,
    });
  }

  async function onClickSaveCore({
    data,
    reset,
  }: {
    data: string;
    reset: () => void;
  }) {
    try {
      isLoadingSave.current = true;

      checkForm();
      const _data = getDiffData(differenceData);
      _data.content = getContent(data);

      const id = source.id;
      await updatePostTemplateMutation.mutateAsync({
        id,
        data: _data,
      });

      setDifferenceData([]);

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.updateCompleted,
      });
    } catch (e) {
      updatePostTemplateMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      isLoadingSave.current = false;
      reset();
    }
  }

  function onClickPreview() {
    setPreviewContent(getContent());
    setIsPreview(!isPreview);
  }

  function checkForm() {
    if (!getContent()) {
      throw translatedFields.tip.contentRequired;
    }
  }

  function onReady({ editor }: { editor: any }) {
    handleEditorStatusChanges({
      editor,
      isDirty,
      setIsActive,
      setIsSaving,
    });
    handleEditorBeforeunload({ editor });
    setEditorContentHtml(editor, form.content);
    editorRef.current = editor;
    setIsReady(true);
  }

  return (
    <Box>
      <form onSubmit={onClickSave} className="vstack gap-4">
        <div className={classNames(isPreview ? 'd-none' : 'd-block')}>
          <label className="form-label">
            {translatedFields.properties.content}
          </label>
          <DynamicEditor
            id={source.section.id}
            type="postTemplate"
            onReadyCallback={onReady}
          />
        </div>

        <div className={classNames(isPreview ? 'd-block' : 'd-none')}>
          {previewContent && <ContentHtml content={previewContent} nodata />}
        </div>

        <div className="hstack gap-4">
          <button
            type="submit"
            disabled={updatePostTemplateMutation.isLoading}
            className="btn btn-success col col-lg-2 my-4"
          >
            {updatePostTemplateMutation.isLoading && <Spinner classs="me-2" />}
            {translatedFields.operate.update}
          </button>

          <button
            onClick={onClickPreview}
            type="button"
            className={classNames(
              'btn col col-lg-2 my-4',
              isPreview ? 'btn-secondary' : 'btn-light',
            )}
          >
            {isPreview
              ? translatedFields.operate.return
              : translatedFields.operate.preview}
          </button>
        </div>
      </form>
    </Box>
  );
}
